<template>
	<view class="page">
		<view>
			<visitor-form 
				v-if="isWechatMpLogin() && (!needLoadDetail || (needLoadDetail && isLoadedDetail))"
				ref="visitorForm" 
				:form-data-prop="handlerProps.formData" 
				:flow-data-prop="handlerProps.flowData"
				@on-enabled-handle="onEnabledHandle" 
				@on-handle-wechatmp="onHandleWechatmp" 
			>
			</visitor-form>
		</view>
		<view class="fixed-button-container" v-if="isWechatMpLogin() && (!needLoadDetail || (needLoadDetail && isLoadedDetail))">
			<u-button type="default" shape="circle" @click="close">返回</u-button>
			<u-button v-if="!isViewMode" type="success" shape="circle" @click="submit" :disabled="isConfirmedMessageTip || isSubmitting">提交</u-button>
		</view>
	</view>
</template>

<script>
	import VisitorForm from '@/pages/flowableplus/work/external/visitor/form.vue';
	import DATATYPE_MAP from '@/pages/flowableplus/work/enums/DataTypeEnum.js';
	import interceptMixin from '@/pages/extAccess/flow/visitor/mixins/interceptMixin.js';
	
	export default {
		components: {
			VisitorForm
		},
		mixins: [interceptMixin()],
		data() {
			return {
				// 是否已确认勾选信息告知
				isConfirmedMessageTip: false,
				// 是否在表单提交进行中
				isSubmitting: false,
				needLoadDetail: false,
				//用于控制在数据加载完后才渲染组件
				isLoadedDetail: false,
				isViewMode: false,
				handlerProps: {
					isShow: false,
					formData: {},
					flowData: {
						flow: {
							flowName: '访客预约'
						},
						curTask: {
							procInsId: '',
							taskId: '',
							procDefKey: '',
							procDefId: '',
							taskDefKey: '',
							fileList: []
						},
						currentUser: {}
					},
					nextTaskInfoList: [],
				},
				// 默认倒计时的秒数
				defaultCountDownSeconds: 3,
				// 倒计时的秒数
				seconds: 0,
				// 定时器Id
				timer: null
			}
		},
		onLoad(params) {
			// onLoad 属于页面生命周期 路由跳转到当前组件才会执行到
			// console.log('onLoad.');
		},
		created() {
			// created 属于组件生命周期
			// console.log('created.');
		},
		onReady() {
			// onReady 属于页面生命周期 路由跳转到当前组件才会执行到
			// console.log('onReady.');
		},
		mounted() {
			// mounted 属于组件生命周期
			// console.log('mounted.');
			this.initData();
		},
		methods: {
			initData() {
				// debugger;
				// if(!this.isWechatMpLogin()) {
				// 	this.handleNotWechatMpLogin();
				// 	return;
				// }
				let id = this.$route.query.id;
				let mode = this.$route.query.mode;
				let procInsId = this.$route.query.procInsId;
				let taskId = this.$route.query.taskId;
				if(id) {
					// 根据id加载表单数据
					this.needLoadDetail = true;
					if (mode == 'view') {
						this.isViewMode = true;
					} else {
						this.isViewMode = false;
					}
					this.$u.api.wflow.business.visitor.detail({
						id
					}).then((res) => {
						// debugger;
						Object.assign(this.handlerProps.formData, res.data);
						this.isLoadedDetail = true;
					});
				} else if(taskId) {
					this.needLoadDetail = true;
					const params = { procInsId: procInsId, taskId: taskId };
					this.$u.api.wflow.business.visitorOuterNetApi.detailProcess(params)
						.then((res) => {
							const data = res.data;
							let processFormList = data.processFormList;
							if(processFormList && processFormList.length > 0) {
								let processForm = processFormList[0];
								if(processForm.externalForm && processForm.externalForm.formData) {
									this.handlerProps.formData = processForm.externalForm.formData;
								}
							}
							this.handlerProps.flowData.curTask = data.taskFormInfo.task;
							this.handlerProps.flowData.currentUser.currentUserId = this.vuex_userId;
							this.handlerProps.flowData.currentUser.currentUserDeptId = this.vuex_deptId;
							this.isLoadedDetail = true;
							// console.log("this.handlerProps",this.handlerProps);
							// debugger;
							if (this.handlerProps.flowData.curTask && this.handlerProps.flowData.curTask.taskDefKey === 'Activity_Initiator'){
								this.isViewMode = false;
							}else {
								this.isViewMode = true;
							}
						})
						.catch((error) => {
							console.error(error);
						});
				}else {
					this.initVisitorBaseInfo();
				}
			},
			/**
			 * 新增预约时，初始访客基本信息
			 */
			initVisitorBaseInfo() {
				if(this.isWechatMpLogin()) {
					this.needLoadDetail = true;
					// id为空则为新增预约
					let params = {
						openId: this.vuex_account
					};
					this.$u.api.wflow.business.visitorOuterNetApi.selectVisitorBaseInfoByOpenId(params)
						.then((res) => {
							const data = res.data;
							data.visitorSex=data.visitorSex.toString();
							Object.assign(this.handlerProps.formData,data);
							this.isLoadedDetail = true;
						}).finally(() => {
							this.isLoadedDetail = true;
						});
				}
			},
			onEnabledHandle(isAllChecked) {
				this.isConfirmedMessageTip = !isAllChecked;
			},
			close() {
				let navigateBackUrl = this.$route.query.navigateBackUrl;
				if(navigateBackUrl) {
					this.$u.route({
						url:navigateBackUrl
					});
				}else {
					uni.setStorageSync('refreshVisitorList', true);
					uni.navigateBack();
				}
			},
			submit() {
				this.isSubmitting = true;
				this.$refs.visitorForm.doHandler();
			},
			onHandleWechatmp(data) {
				// console.log(data);
				if(data.verifyResult) {
					this.handlerProps.isShow = false;
					this.handlerProps.formData = data.formData;
					this.handlerProps.flowData = Object.assign(this.handlerProps.flowData,data.flowData);
					this.doComplete();
				}else {
					// 表单检验失败时，则isSubmitting置false
					this.isSubmitting = false;
				}
				
			},
			async doComplete() {
				let handleResult = await this.initNextUserNode();
				if(!handleResult || this.handlerProps.nextTaskInfoList.length == 0) {
					this.isSubmitting = false;
					this.$u.toast('提交失败');
					return;
				}
				handleResult = await this.resolveNextUsers();
				if(!handleResult 
					|| !this.handlerProps.nextTaskInfoList[0]['nextUsers'] 
					|| this.handlerProps.nextTaskInfoList[0]['nextUsers'].length == 0) {
					this.isSubmitting = false;
					this.$u.toast('提交失败');
					return;
				}
				let result = await this.finallySubmit();
				if(result.success) {
					// this.$u.toast('提交成功');
					// this.doNavigateBack();
					
					// 增加延时倒计时提示后跳转返回
					this.delayNavigate('提交成功');
				}else {
					if(result.msg!=null && result.msg!=''){
						uni.showToast({
							title: result.msg,
							duration: 2000
						});
					}else{
						uni.showToast({
							title: "流程提交失败！",
							duration: 2000
						});
					}
					
					this.isSubmitting = false;
				}
				
			},
			/**
			 * 获取预约访客的【发起人】任务节点的下一个用户任务节点
			 */
			async initNextUserNode() {
				let flowData = this.handlerProps.flowData;
				let taskDefKey = flowData.curTask.taskDefKey;
				let procDefId = flowData.curTask.procDefId;
				let procDefKey = flowData.curTask.procDefKey;
				let params = {
					procDefId,
					procDefKey,
					taskDefKey
				};
				let handleResult = true;
				let url = this.vuex_config.adminPath + '/api/blade-flowable-plus/processVisitorOuterNetApi/nextFlowNodeByTaskVO';
				try {
					let res = await this.$u.get(url, params);
					// console.log("await回来的res: ",res);
					// 清空数组this.handlerProps.nextTaskInfoList
					this.handlerProps.nextTaskInfoList.splice(0, this.handlerProps.nextTaskInfoList.length);
					let data = res.data;
					if (data && data.length > 0) {
						data.forEach((node, index) => {
							// 任务节点定义ID
							let taskDefKey = node.id;
							// 任务节点名称
							let taskDefName = node.name;
							// 候选用户el表达式
							let candidateUsersExpression = '';
							if (node.candidateUsers && node.candidateUsers.length > 0) {
								candidateUsersExpression = node.candidateUsers[0];
							}
							// 候选用户的数据源请求地址
							let dataSourceUrl = '';
							let attributes = node.attributes;
							let nextUsers = [];
							let selectUserDisplay = false;
							//结束节点
							if (node.assignee === undefined) {
								let taskDefNode = {
									taskDefKey,
									taskDefName,
									nextUsers,
									selectUserDisplay
								};
								this.handlerProps.nextTaskInfoList.push(taskDefNode);
							} else if (attributes && attributes.dataType && attributes.dataType.length > 0 && attributes.text && attributes.text.length > 0) {
								let value = attributes.dataType[0].value;
								let text = attributes.text[0].value;
								if (value === DATATYPE_MAP.CANDIDATEUSERS_API_GET && text) {
									dataSourceUrl = text;
								}
								if (node.assignee !== '${initiator}') {
									selectUserDisplay = true;
								}
								let taskDefNode = {
									taskDefKey,
									taskDefName,
									candidateUsersExpression,
									dataSourceUrl,
									nextUsers,
									selectUserDisplay
								};
								this.handlerProps.nextTaskInfoList.push(taskDefNode);
							}
						});
					}
					handleResult = true;
				}catch(error) {
					// console.log('error',error);
					handleResult = false;
				};
				return handleResult;
			},
			async resolveNextUsers() {
				let formData = this.handlerProps.formData;
				let flowData = this.handlerProps.flowData;
				// 1. 解析所有的占位符变量数组，eg: ['${intervieweePhone}','${currentUserDeptId}'],${}里面的内容对应的是页面表单的变量
				let placeholderVars = [];
				let selectedNextTask = this.handlerProps.nextTaskInfoList[0];
				let { taskDefKey, taskDefName, dataSourceUrl } = selectedNextTask;
				let handleResult = true;
				if (dataSourceUrl) {
					// 将下面的api地址替换为相应的外网地址 2024-02-27
					let sourceUrl = '/api/blade-flowable-plus/workflow/getCandidateUsers';
					let targetUrl = '/api/blade-flowable-plus/processVisitorOuterNetApi/getCandidateUsersByPhone';
					dataSourceUrl = dataSourceUrl.replace(sourceUrl,targetUrl);
					
					// 解析？后面的参数
					let paramsStr = dataSourceUrl.substring(dataSourceUrl.indexOf('?') + 1);
					if (paramsStr) {
						let paramArr = paramsStr.split('&');
						if (paramArr && paramArr.length > 0) {
							paramArr.forEach((param) => {
								let paramContent = param.split('=');
								if (paramContent && paramContent.length === 2 && paramContent[1].indexOf('$') !== -1) {
									placeholderVars.push(paramContent[1]);
								}
							});
						}
					}
					// 2. 查找占位符变量对应的表单属性与属性值
					let placeholderVarRealValueObj = {};
					placeholderVars.forEach((pvar) => {
						let formPropKey = pvar.replace('${', '').replace('}', '');
						if (formData[formPropKey]) {
							// 有实际值放到placeholderVarRealValueObj中
							placeholderVarRealValueObj[pvar] = formData[formPropKey];
						}
						if (flowData.curTask[formPropKey]) {
							// 有实际值放到placeholderVarRealValueObj中
							placeholderVarRealValueObj[pvar] = flowData.curTask[formPropKey];
						}
						if (flowData.currentUser[formPropKey]) {
							// 有实际值放到placeholderVarRealValueObj中
							placeholderVarRealValueObj[pvar] = flowData.currentUser[formPropKey];
						}
						if (formPropKey === 'nextTaskDefKey') {
							placeholderVarRealValueObj[pvar] = this.nextTaskInfoList[0].taskDefKey;
						}
					});
					// 3. 发起请求调用获取下一环节审批人接口
					let sendArr = [];
					for (let key in placeholderVarRealValueObj) {
						if (placeholderVarRealValueObj.hasOwnProperty(key)) {
							dataSourceUrl = dataSourceUrl.replace(key, placeholderVarRealValueObj[key]);
						}
					}
					// console.log('解析后的dataSourceUrl', dataSourceUrl);
					//如果dataSourceUrl中还有${}占位变量没有解析，则不进行请求加载
					if (dataSourceUrl && dataSourceUrl.indexOf('${') === -1) {
						let apiUrl = this.vuex_config.adminPath + dataSourceUrl;
						sendArr.push(apiUrl);
					}
					let handleResult = true;
					try {
						let results = await Promise.all(sendArr.map((sendEndpoint) => this.$u.get(this.vuex_config.adminPath + sendEndpoint)));
						if (results && results.length > 0) {
						  results.forEach((result, index) => {
						    let nextUserTaskInfo = this.handlerProps.nextTaskInfoList[index];
						    nextUserTaskInfo['nextUsers'] = result.data || [];
						  })
						}else {
							handleResult = false;
						}
					}catch(error) {
						// console.log('error',error);
						handleResult = false;
					}
				}
				return handleResult;
			},
			async finallySubmit() {
				const params = {
					variables: this.handlerProps.formData
				};
				let mergedJson = Object.assign(params, this.handlerProps.flowData.curTask);
				mergedJson.nextTaskInfoList = this.handlerProps.nextTaskInfoList.filter((item,index) => index === 0);
				if (this.handlerProps.flowData.flow) {
					mergedJson.title = this.handlerProps.formData.visitorName + '[' + this.handlerProps.flowData.flow.flowName + ']';
				}
				if(mergedJson.comment && typeof mergedJson.comment === 'object') {
					// detailProcess详情返回的对象中comment为{}则特殊处理下设置为空字符串
					mergedJson.comment = '';
				}
				// console.log('提交访客预约流程的报文', mergedJson);
				let result={};
				try {
					return await this.$u.api.wflow.business.visitorOuterNetApi.submitFlow(mergedJson);
				}catch(error) {
					console.log('error',error);
					let result={success:false,msg:error};
					return result
				}
				
			},
			doNavigateBack() {
				let navigateBackUrl = this.$route.query.navigateBackUrl;
				if(navigateBackUrl) {
					this.$u.route({
						url:navigateBackUrl
					});
				}else {
					uni.setStorageSync('refreshVisitorList', true);
					uni.navigateBack();
				}
			},
			/**
			 * 展示倒计时的提示消息
			 * 
			 * @param {Object} content 提示文字内容
			 */
			showTips(content) {
				// 调用 uni.showToast() 方法，展示提示消息
				uni.showToast({
					// 不展示任何图标
					icon: 'none',
					// 提示的消息
					title: content,
					// 为页面添加透明遮罩，防止点击穿透
					mask: true,
					// 1.5 秒后自动消失
					duration: 1500,
				})
			},
			/**
			 * 延迟导航到相应页面
			 * 
			 */
			delayNavigate(content = '') {
				let tipTemplateContent = content + ',' + '{second}秒后自动跳转';
				// 将data中的秒数重置成默认的倒计时秒数
				this.seconds = this.defaultCountDownSeconds;
				let reallyContent = tipTemplateContent.replace('{second}',this.seconds);
				this.showTips(reallyContent);
				this.timer = setInterval(() => {
				  this.seconds--;
				  if (this.seconds <= 0) {
				    clearInterval(this.timer);
					this.doNavigateBack();
				    return;
				  }
				  let reallyContent = tipTemplateContent.replace('{second}',this.seconds);
				  this.showTips(reallyContent);
				}, 1000)
			},
		},
	}
</script>

<style lang="scss" scoped>
  .page {
    height: 100vh;
    background: #F7F7F7;
    overflow: auto;
  }
  
	.fixed-button-container {
		display: flex; 
		flex-direction: row;
		justify-content: center;
		
		button {
			width: 50%;
			margin-bottom: 10rpx;
		}
		button + button {
			margin-left: 10rpx;
			margin-bottom: 10rpx;
		}
	}
</style>